import os
import requests
import json
import logging
import time
import threading
import zipfile
from pathlib import Path
from flask import Flask, request, jsonify, send_file
from flask_cors import CORS
from dotenv import load_dotenv

# 配置日志
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    filename='offline_content_debug.log',
    filemode='a'
)
logger = logging.getLogger('offline_content')

# 调试模式标志 - 设置为False以使用实际的LLM API调用
DEBUG_MODE = False

# 加载环境变量
load_dotenv()

app = Flask(__name__)
CORS(app)  # 允许跨域请求

# 获取API密钥
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_API_KEY:
    logger.error("未设置OPENAI_API_KEY环境变量")
    raise ValueError("请在.env文件中设置OPENAI_API_KEY")

# API端点
OPENAI_API_URL = "https://api.openai.com/v1/chat/completions"

# 可用目的地API
@app.route('/api/available_destinations', methods=['GET'])
def available_destinations():
    logger.debug("请求可用目的地API")
    # 当前开放的目的地
    available = {
        'tokyo': {
            'name': '东京',
            'country': '日本',
            'language': 'ja',
            'available': True,
            'packages': ['language', 'map', 'culture'],
            'languageSize': 45,
            'mapSize': 85,
            'cultureSize': 30
        },
        'paris': {
            'name': '巴黎',
            'country': '法国',
            'language': 'fr',
            'available': True,
            'packages': ['language', 'map', 'culture'],
            'languageSize': 50,
            'mapSize': 90,
            'cultureSize': 35
        },
        'newyork': {
            'name': '纽约',
            'country': '美国',
            'language': 'en',
            'available': True,
            'packages': ['language', 'map', 'culture'],
            'languageSize': 40,
            'mapSize': 95,
            'cultureSize': 32
        },
        'rome': {
            'name': '罗马',
            'country': '意大利',
            'language': 'it',
            'available': False,
            'coming_soon': True,
            'eta': '2025年7月'
        },
        'bangkok': {
            'name': '曼谷',
            'country': '泰国',
            'language': 'th',
            'available': False,
            'coming_soon': True,
            'eta': '2025年8月'
        },
        'london': {
            'name': '伦敦',
            'country': '英国',
            'language': 'en',
            'available': False,
            'coming_soon': True,
            'eta': '2025年9月'
        }
    }
    
    return jsonify({
        'destinations': available,
        'total_available': 3,
        'coming_soon': 3
    })

# 离线内容包下载API
@app.route('/api/download_package', methods=['POST'])
def download_package():
    logger.debug(f"收到下载请求: {request.json}")
    data = request.json
    destination = data.get('destination', '')
    package_type = data.get('package_type', '')
    
    # 检查目的地是否可用
    destinations = {
        'tokyo': {
            'name': '东京',
            'country': '日本',
            'language': 'ja',
            'available': True
        },
        'paris': {
            'name': '巴黎',
            'country': '法国',
            'language': 'fr',
            'available': True
        },
        'newyork': {
            'name': '纽约',
            'country': '美国',
            'language': 'en',
            'available': True
        },
        'rome': {
            'name': '罗马',
            'country': '意大利',
            'language': 'it',
            'available': False,
            'eta': '2025年7月'
        },
        'bangkok': {
            'name': '曼谷',
            'country': '泰国',
            'language': 'th',
            'available': False,
            'eta': '2025年8月'
        },
        'london': {
            'name': '伦敦',
            'country': '英国',
            'language': 'en',
            'available': False,
            'eta': '2025年9月'
        }
    }
    
    if not destination or not package_type:
        logger.warning(f"请求缺少必要参数: destination={destination}, package_type={package_type}")
        return jsonify({"error": "请提供目的地和包类型"}), 400
    
    if destination not in destinations:
        logger.warning(f"不支持的目的地: {destination}")
        return jsonify({"error": "不支持的目的地"}), 400
    
    if not destinations[destination]['available']:
        logger.info(f"请求了未开放的目的地: {destination}")
        return jsonify({
            "error": "目的地暂不可用",
            "destination": destination,
            "name": destinations[destination]['name'],
            "eta": destinations[destination]['eta']
        }), 400
    
    if package_type not in ['language', 'map', 'culture']:
        logger.warning(f"不支持的包类型: {package_type}")
        return jsonify({"error": "不支持的包类型"}), 400
    
    # 生成唯一下载ID
    download_id = f"{destination}_{package_type}_{int(time.time())}"
    logger.info(f"生成下载ID: {download_id}")
    
    # 包大小信息
    package_sizes = {
        'tokyo': {'language': 45, 'map': 85, 'culture': 30},
        'paris': {'language': 50, 'map': 90, 'culture': 35},
        'newyork': {'language': 40, 'map': 95, 'culture': 32}
    }
    
    # 创建离线内容目录
    offline_dir = Path("offline_content")
    offline_dir.mkdir(exist_ok=True)
    logger.debug(f"创建离线内容目录: {offline_dir}")
    
    # 在后台线程中生成内容
    threading.Thread(
        target=generate_offline_content,
        args=(download_id, destination, package_type, destinations[destination])
    ).start()
    
    # 返回下载信息
    return jsonify({
        "success": True,
        "destination": destination,
        "package_type": package_type,
        "size_mb": package_sizes[destination][package_type],
        "download_id": download_id,
        "status_url": f"/api/download_status/{download_id}"
    })

# 下载状态API
@app.route('/api/download_status/<download_id>', methods=['GET'])
def download_status(download_id):
    logger.debug(f"检查下载状态: {download_id}")
    # 解析下载ID
    try:
        parts = download_id.split('_')
        destination = parts[0]
        package_type = parts[1]
    except:
        logger.error(f"无效的下载ID: {download_id}")
        return jsonify({"error": "无效的下载ID"}), 400
    
    # 检查文件是否已生成
    offline_dir = Path("offline_content")
    zip_file = offline_dir / f"{download_id}.zip"
    
    if zip_file.exists():
        logger.info(f"下载已完成: {download_id}")
        return jsonify({
            "status": "completed",
            "download_url": f"/api/download_file/{download_id}",
            "destination": destination,
            "package_type": package_type
        })
    else:
        # 检查是否正在生成
        temp_file = offline_dir / f"{download_id}.generating"
        if temp_file.exists():
            # 读取进度
            try:
                with open(temp_file, 'r') as f:
                    progress = f.read().strip()
                    progress = int(progress) if progress.isdigit() else 0
                logger.debug(f"下载进度: {download_id} - {progress}%")
            except Exception as e:
                logger.error(f"读取进度失败: {e}")
                progress = 0
                
            return jsonify({
                "status": "generating",
                "progress": progress,
                "destination": destination,
                "package_type": package_type
            })
        else:
            logger.warning(f"下载任务不存在: {download_id}")
            return jsonify({
                "status": "not_found",
                "error": "下载任务不存在或已过期"
            }), 404

# 文件下载API
@app.route('/api/download_file/<download_id>', methods=['GET'])
def download_file(download_id):
    logger.info(f"请求下载文件: {download_id}")
    
    offline_dir = Path("offline_content")
    zip_file = offline_dir / f"{download_id}.zip"
    
    if zip_file.exists():
        logger.debug(f"发送文件: {zip_file}")
        return send_file(
            zip_file,
            mimetype='application/zip',
            as_attachment=True,
            download_name=f"{download_id}.zip"
        )
    else:
        logger.error(f"文件不存在: {download_id}")
        return jsonify({"error": "文件不存在"}), 404

# 使用LLM生成内容
def generate_content_with_llm(prompt, system_prompt):
    if DEBUG_MODE:
        logger.debug(f"模拟生成内容，提示: {prompt[:100]}...")
        # 返回模拟数据
        if "短语" in prompt:
            return json.dumps([
                {"phrase": "こんにちは", "pronunciation": "Kon'nichiwa", "translation": "你好", "usage": "打招呼"},
                {"phrase": "ありがとう", "pronunciation": "Arigatō", "translation": "谢谢", "usage": "表达感谢"}
            ], ensure_ascii=False)
        elif "对话" in prompt:
            return json.dumps({"scenario": "餐厅", "conversation": [{"speaker": "顾客", "text": "一个示例对话"}]})
        elif "POI" in prompt:
            return json.dumps([
                {"id": "poi1", "name": "东京塔", "type": "景点", "coordinates": [139.7454, 35.6586], "address": "东京都港区芝公园4丁目2-8", "description": "东京的标志性建筑"}
            ])
        elif "路线" in prompt:
            return json.dumps([
                {"name": "东京一日游", "description": "东京经典景点一日游", "duration": "8小时", "points": [{"poi_id": "poi1", "name": "东京塔", "stay_time": "1小时"}]}
            ])
        else:
            return json.dumps({"title": "示例内容", "content": "这是调试模式下的示例内容"})
    else:
        headers = {
            "Authorization": f"Bearer {OPENAI_API_KEY}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "gpt-3.5-turbo",
            "messages": [
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": prompt}
            ],
            "temperature": 0.7
        }
        
        try:
            logger.debug(f"调用LLM API生成内容")
            response = requests.post(OPENAI_API_URL, headers=headers, json=payload)
            response.raise_for_status()
            result = response.json()
            content = result["choices"][0]["message"]["content"]
            logger.debug(f"LLM API调用成功，返回内容长度: {len(content)}")
            return content
        except Exception as e:
            logger.error(f"生成内容失败: {str(e)}")
            # 返回一个简单的错误JSON
            return json.dumps({"error": str(e)})

# 生成离线内容
def generate_offline_content(download_id, destination, package_type, destination_info):
    logger.info(f"开始生成离线内容: {download_id}")
    offline_dir = Path("offline_content")
    temp_file = offline_dir / f"{download_id}.generating"
    zip_file = offline_dir / f"{download_id}.zip"
    content_dir = offline_dir / download_id
    
    try:
        # 创建临时文件记录进度
        with open(temp_file, 'w') as f:
            f.write("0")
        
        # 创建内容目录
        content_dir.mkdir(exist_ok=True)
        logger.debug(f"创建内容目录: {content_dir}")
        
        # 根据包类型生成不同内容
        if package_type == 'language':
            generate_language_package(content_dir, destination, destination_info, temp_file)
        elif package_type == 'culture':
            generate_culture_package(content_dir, destination, destination_info, temp_file)
        elif package_type == 'map':
            generate_map_package(content_dir, destination, destination_info, temp_file)
        
        # 创建ZIP文件
        logger.info(f"创建ZIP文件: {zip_file}")
        with zipfile.ZipFile(zip_file, 'w', zipfile.ZIP_DEFLATED) as zipf:
            for file in content_dir.glob('**/*'):
                if file.is_file():
                    zipf.write(file, file.relative_to(content_dir))
        
        # 更新进度为100%
        with open(temp_file, 'w') as f:
            f.write("100")
        logger.info(f"内容生成完成: {download_id}")
            
    except Exception as e:
        # 记录错误
        logger.error(f"生成内容失败: {download_id} - {str(e)}")
        with open(offline_dir / f"{download_id}_error.log", 'w') as f:
            f.write(str(e))
    finally:
        # 清理临时文件和目录
        import shutil
        if content_dir.exists():
            shutil.rmtree(content_dir)
            logger.debug(f"清理内容目录: {content_dir}")

# 生成语言包
def generate_language_package(content_dir, destination, destination_info, progress_file):
    logger.info(f"使用LLM API生成语言包: {destination}")
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("10")
    
    # 目的地信息
    dest_name = destination_info['name']
    country = destination_info['country']
    language = destination_info.get('language', 'en')
    
    # 生成常用短语
    logger.debug(f"生成{dest_name}的常用短语")
    phrases_prompt = f"请提供在{dest_name}({country})旅行时最常用的10个{language}短语，包括发音指导和中文翻译。格式为JSON数组，每个对象包含phrase(原文)、pronunciation(发音)、translation(中文翻译)和usage(使用场景)字段。"
    phrases = generate_content_with_llm(phrases_prompt, "你是一个专业的语言教师，擅长创建实用的语言学习材料。")
    
    # 保存常用短语
    with open(content_dir / "phrases.json", 'w', encoding='utf-8') as f:
        f.write(phrases)
    
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("50")
    
    # 创建信息文件
    info = {
        "destination": destination,
        "name": dest_name,
        "country": country,
        "language": language,
        "package_type": "language",
        "version": "1.0",
        "created_at": time.strftime("%Y-%m-%d %H:%M:%S"),
        "content": ["phrases.json"]
    }
    
    # 保存语言包信息
    with open(content_dir / "info.json", 'w', encoding='utf-8') as f:
        json.dump(info, f, ensure_ascii=False, indent=2)
    
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("90")
    
    logger.info(f"语言包生成完成: {destination}")

# 生成文化包
def generate_culture_package(content_dir, destination, destination_info, progress_file):
    logger.info(f"使用LLM API生成文化包: {destination}")
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("10")
    
    # 目的地信息
    dest_name = destination_info['name']
    country = destination_info['country']
    
    # 生成历史背景
    logger.debug(f"生成{dest_name}的历史背景")
    history_prompt = f"请提供关于{dest_name}({country})的简要历史背景，包括重要历史事件。格式为JSON对象，包含title(标题)、overview(概述)和sections(章节数组，每个章节包含subtitle和content)。"
    history = generate_content_with_llm(history_prompt, "你是一个专业的历史学者，擅长提供准确、简洁的历史知识。")
    
    # 保存历史背景
    with open(content_dir / "history.json", 'w', encoding='utf-8') as f:
        f.write(history)
    
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("50")
    
    # 创建信息文件
    info = {
        "destination": destination,
        "name": dest_name,
        "country": country,
        "package_type": "culture",
        "version": "1.0",
        "created_at": time.strftime("%Y-%m-%d %H:%M:%S"),
        "content": ["history.json"]
    }
    
    # 保存文化包信息
    with open(content_dir / "info.json", 'w', encoding='utf-8') as f:
        json.dump(info, f, ensure_ascii=False, indent=2)
    
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("90")
    
    logger.info(f"文化包生成完成: {destination}")

# 生成地图包
def generate_map_package(content_dir, destination, destination_info, progress_file):
    logger.info(f"使用LLM API生成地图包: {destination}")
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("10")
    
    # 目的地信息
    dest_name = destination_info['name']
    country = destination_info['country']
    
    # 生成POI数据
    logger.debug(f"生成{dest_name}的POI数据")
    poi_prompt = f"请提供{dest_name}({country})的5个主要兴趣点(POI)数据，包括景点。格式为JSON数组，每个对象包含id、name(名称)、type(类型)、coordinates(坐标，格式为[经度,纬度])、address(地址)和description(描述)字段。"
    pois = generate_content_with_llm(poi_prompt, "你是一个专业的地理信息专家，擅长提供准确的位置数据和描述。")
    
    # 保存POI数据
    with open(content_dir / "pois.json", 'w', encoding='utf-8') as f:
        f.write(pois)
    
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("50")
    
    # 创建信息文件
    info = {
        "destination": destination,
        "name": dest_name,
        "country": country,
        "package_type": "map",
        "version": "1.0",
        "created_at": time.strftime("%Y-%m-%d %H:%M:%S"),
        "content": ["pois.json"]
    }
    
    # 保存地图包信息
    with open(content_dir / "info.json", 'w', encoding='utf-8') as f:
        json.dump(info, f, ensure_ascii=False, indent=2)
    
    # 更新进度
    with open(progress_file, 'w') as f:
        f.write("90")
    
    logger.info(f"地图包生成完成: {destination}")

# 测试LLM调用API
@app.route('/api/debug/test_llm', methods=['POST'])
def test_llm():
    logger.debug("测试LLM API调用")
    data = request.json
    prompt = data.get('prompt', '请生成一个简短的旅行短语')
    system = data.get('system', '你是一个专业的语言教师')
    
    try:
        result = generate_content_with_llm(prompt, system)
        return jsonify({
            "success": True,
            "result": result
        })
    except Exception as e:
        logger.error(f"LLM API调用失败: {str(e)}")
        return jsonify({
            "success": False,
            "error": str(e)
        }), 500

# 调试API - 查看所有下载任务
@app.route('/api/debug/downloads', methods=['GET'])
def debug_downloads():
    logger.debug("请求调试API: 查看所有下载任务")
    offline_dir = Path("offline_content")
    
    # 收集所有下载任务
    downloads = []
    
    # 检查生成中的任务
    for file in offline_dir.glob("*.generating"):
        try:
            with open(file, 'r') as f:
                progress = f.read().strip()
            
            download_id = file.stem
            parts = download_id.split('_')
            
            downloads.append({
                "id": download_id,
                "destination": parts[0] if len(parts) > 0 else "unknown",
                "package_type": parts[1] if len(parts) > 1 else "unknown",
                "status": "generating",
                "progress": progress
            })
        except Exception as e:
            logger.error(f"读取生成进度失败: {e}")
    
    # 检查已完成的任务
    for file in offline_dir.glob("*.zip"):
        download_id = file.stem
        parts = download_id.split('_')
        
        downloads.append({
            "id": download_id,
            "destination": parts[0] if len(parts) > 0 else "unknown",
            "package_type": parts[1] if len(parts) > 1 else "unknown",
            "status": "completed",
            "size": file.stat().st_size
        })
    
    return jsonify({
        "downloads": downloads,
        "count": len(downloads)
    })

if __name__ == '__main__':
    app.run(debug=True, port=5001)  # 使用不同的端口避免与主API冲突